package com.ay.weixin.config;

import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.lizar.controller.loader.EventLoader;
import org.lizar.exception.GroupCodeIsNotExists;
import org.lizar.ioc.Container;
import org.lizar.ioc.module.Module;
import org.lizar.log.Log;
import org.lizar.log.Logger;
import org.lizar.util.StringHelper;

import com.ay.weixin.config.group.ProjectGroupVar;
import com.ay.weixin.config.group.db.IbatisProjectGroupVarDao;
import com.ay.weixin.config.group.exception.ProjectNotExists;
import com.ay.weixin.config.group.exception.ProjectVarNotExists;
import com.ay.weixin.fdc.admin.customer.db.IbatisWeiXinProjectDao;
import com.ay.weixin.fdc.admin.customer.domain.WeiXinProject;
import com.ay.weixin.fdc.admin.customer.domain.WeiXinProject.WeiXinProjectStatus;

/**
 * 
 * 项目配置
 * 
 * */
public class ProjectConfig extends Module {
	
	private static Log										log				= Logger.newInstance(ProjectConfig.class);
	
	private static IbatisProjectGroupVarDao					varDao;
	
	private static IbatisWeiXinProjectDao					projectDao;
	
	private static TreeMap<String, ProjectGroupVar>			defaultCodeMap	= new TreeMap<String, ProjectGroupVar>();
	
	private static Map<Long, Map<String, ProjectGroupVar>>	codeMap			= new HashMap<Long, Map<String, ProjectGroupVar>>();
	
	private static Map<Long, WeiXinProject>					projects		= new HashMap<Long, WeiXinProject>();
	
	@Override
	public void init_property() {
		varDao = Container.get(IbatisProjectGroupVarDao.class);
		projectDao = Container.get(IbatisWeiXinProjectDao.class);
	}
	
	public ProjectConfig() {
		
	}
	
	
	@Override
	public void init_component() throws Exception {
		setUpGroup();
		loadAllRunningProjects();
	}
	
	private void setUpGroup() {
		
		
		
		
		
		
		
		setUp("sys", "copy_right", "爱友微信", "底部copy right显示");
		
		setUp("sys", "token", "weixin", "传输验证数据，微信与平台自定义一致");
		
		setUp("sys", "AppId", "wx82baf8ed646466ff", "AppId");
		
		
		setUp("sys", "AppSecret", "c1b8530dc8fefca88557550c085bb0fc", "AppSecret");
		
		
		//只允许微信访问页面
		setUp("sys", "weixin_only", true, "页面只允许微信访问");
		//系统自定义配置
		setUp("sys", "max_image_file_size", 300, "文件大小KB");
		//wx-用户
		setUp("weixin_api_user", "scope_level", "snsapi_base", "授权级别,备选值 snsapi_base或snsapi_userinfo");
		//wx-回复
		setUp("weixin_api_auto_reply", "default_msg_reply", true, "对于未知输入启动自动回复");
				
		//用户管理配置
		setUp("fdc_usercenter", "enable_salesman", true, "是否启用销售人员");
		setUp("fdc_usercenter", "register_need_verify_manually", true, "用户注册，是否需要审核");
		setUp("fdc_usercenter", "register_need_upload_business_card", true, "用户注册，是否需要上传名片");
		setUp("fdc_usercenter", "register_need_upload_ID_card", true, "用户注册，是否需要上传身份证");
		setUp("fdc_usercenter", "register_forced_business_card", true, "用户注册，上传名片是否为必填");
		setUp("fdc_usercenter", "register_forced_ID_card", true, "用户注册，上传身份证是否为必填");
		setUp("fdc_usercenter", "register_need_invate_code", true, "经纪人注册，是否需要邀请码");
		setUp("fdc_usercenter", "register_need_old_house", true, "老带新注册，是否需要小区信息");
		setUp("fdc_usercenter", "register_need_id_card_no", true, "经纪人注册，是否需要身份证号");
		setUp("fdc_usercenter", "register_confirm_benifit", true, "用户注册是否固定奖励");
		setUp("fdc_usercenter", "register_invate_benifit", true, "用户注册邀请者是否奖励");
		setUp("fdc_usercenter", "register_benifit_for_new_commer", true, "用户注册是否奖励");
		setUp("fdc_usercenter", "register_benifit_value", 1, "用户注册奖励金额");
		setUp("fdc_usercenter", "register_invate_benifit_value", 1, "用户注册邀请者奖励金额");
		setUp("fdc_usercenter", "register_invate_benifit_rules", "0.1~0.5:0.4,0.5~1:0.3,1~1.5:0.2,1.5~2:0.1", "邀请用户注册随机奖励规则0.1~0.5元概率40%,0.5~1概率30%,1~1.5概率20%,1.5~2概率10%(暂时未启用)");
		setUp("fdc_usercenter", "vcode_used_error_in_times", 3, "用户连续登陆失败三次后要求输入验证码");
		
		//看房配置
		setUp("fdc_kanfang", "max_recommand_submit", 5, "每天最大推荐数");
		setUp("fdc_kanfang", "income_for_recommand", true, "推荐有奖");
		setUp("fdc_kanfang", "recommand_confirm_benifit", false, "推荐是否为固定奖励");
		setUp("fdc_kanfang", "recommand_benifit_value", 1, "推荐固定奖励金额");
		setUp("fdc_kanfang", "recommand_invite_benifit_rules", "0.1~0.5:0.4,0.5~1:0.3,1~1.5:0.2,1.5~2:0.1", "推荐随机奖励规则");
		setUp("fdc_kanfang", "recommand_return", "推荐有奖", "奖励名称");
		setUp("fdc_kanfang", "yongjin_jingjiren_rate", 0.05, "经纪人收益分红比例");
		setUp("fdc_kanfang", "yongjin_old_cus_rate", 0.05, "老带新经纪人收益分红比例");
		setUp("fdc_kanfang", "user_black_list_limit", 5, "用户反复提交多次无效数据，将被列入黑名单");
		setUp("fdc_kanfang", "yongjin_return", "推荐购房佣金", "推荐购房佣金");
		setUp("fdc_kanfang", "recommand_onvisit", "推荐到访佣金", "推荐到访佣金");
		setUp("fdc_kanfang", "yongjin_jingjiren_return", "我的经纪人收益分红", "经纪人收益分红");
		setUp("fdc_kanfang", "email_notify_enable", false, "是否启用看房邮件通知");
		setUp("fdc_kanfang", "notify_email", "594382300@qq.com", "看房通知");
		
		//看房列表页面设置
		setUp("fdc_project_setting", "yuyue_page_title", "预约看房", "预约看房提交表单处");
		setUp("fdc_project_setting", "list_page_title", "泰禾益丰项目中心", "房地产首页名称");
		
		//账务流水
		setUp("fdc_cash_flow", "withdraw_more_than", 0, "用户提现申请最小额度");
		setUp("fdc_cash_flow", "withdraw_days_limit", 7, "每隔多少天允许提现一次");
		setUp("fdc_cash_flow", "submit_notify_enable", false, "是否启用佣金提现申请邮件通知");
		setUp("fdc_cash_flow", "submit_notify_email", "594382300@qq.com", "佣金提现申请通知邮箱");
		setUp("fdc_cash_flow", "withdraw", "佣金提现", "佣金提现");
		setUp("fdc_cash_flow", "page_size", 50, "出入金流水，每页数量");
		
		//邮箱
		setUp("mailbox", "mail_server", "smtp.exmail.qq.com", "邮件服务器");
		setUp("mailbox", "mail_server_port", "25", "邮件服务器端口");
		setUp("mailbox", "user_name", "system@cutool.com", "登录名");
		setUp("mailbox", "password", "zhoubo20070409", "密码");
		setUp("mailbox", "email_personal_name", "爱有微信平台", "邮箱验证，发信人名字");
		
		//活动
		setUp("share", "backhits_by_ip_or_openid", "ip", "分享规则");
		
		
		//多客服
		setUp("duokefu", "open", true, "是否开启多客服");
		setUp("duokefu", "transfer_key", "客服", "多客服转移关键字");
		
		//消息模板
		setUp("fdc_usercenter", "account_open_template_msg_id", "-V5uk5p0dlkufRsVFcaWiRj-N4yhb3h23C28kkWbjt0", "消息模板-TM00239-账户开通提醒");
		setUp("fdc_usercenter", "account_update_template_msg_id", "kiswI5uwAv2aXG1LNXgoFlvjuZlOB0adoPab3zOggIk", "消息模板-OPENTM201078459-账户信息变更提醒");
		setUp("fdc_cash_flow", "withdraw_template_id", "YaD8CPHSsq-BEk3grnUILA8Zzmc3U3ee7cxL604tM9w", "消息模板-TM00242-存入或提现成功通知");
		setUp("fdc_cash_flow", "receive_yongjin_msg_template_id", "2afO4x1a9l-negAfvgQI96LIHvSDPtdY_E4Z3K5K80I", "消息模板-TM00834-佣金发放通知");
		setUp("fdc_kanfang", "customer_change_template_msg_id", "26jGMGxde16Wyncwt0lhrs_FcPVk2IN4mZIjuBQo2yA", "消息模板-TM00836-客户状态变动通知");
		setUp("fdc_kanfang", "book_template_msg_id", "pwvEyMcSgByPen4Wj0Va-q_iwtB63rDYdzCDwnsZY5E", "消息模板-TM00130-预约看房通知");
	}
	
	public static String toFullCode(String group, String code) {
		StringBuilder fullCode = new StringBuilder(group);
		fullCode.append(".").append(code);
		return fullCode.toString();
	}
	
	private  void setUp(String group, String code, Object value, String desc) {
		ProjectGroupVar var = new ProjectGroupVar();
		var.setGroup(group);
		var.setCode(code);
		var.setValue(value);
		var.setDesc(desc);
		defaultCodeMap.put(toFullCode(group, code), var);
	}
	
	private static void storeNewProjectVars(long project_id) throws SQLException {
		for (ProjectGroupVar var : defaultCodeMap.values()) {
			var.setProject_id(project_id);
			varDao.insert(var);
		}
	}
	
	public static void loadSysConfig(EventLoader el,long project_id){
		Map<String, ProjectGroupVar> vars 	=codeMap.get(project_id);
		if(vars==null){
			throw new ProjectNotExists(project_id);
		}
		for(ProjectGroupVar var:vars.values()){
			if(StringHelper.equals(var.getGroup(), "sys")){
				el.setAttr(var.getGroup()+"_"+var.getCode(), var.getValue());
			}
		}
	}
	
	/**
	 * 
	 * 检查数据是否重复或者缺失
	 * @throws SQLException 
	 * 
	 * */
	private static void deleteNotUsedAndInsertNew(long project_id, Collection<ProjectGroupVar> allVars) throws SQLException {
		Iterator<ProjectGroupVar> itr = allVars.iterator();
		ProjectGroupVar var = null;
		for (; itr.hasNext();) {
			var = itr.next();
			if (defaultCodeMap.get(var.getFullCode()) == null) {
				varDao.deleteById(var.getId());
				itr.remove();
			}
		}
		for (ProjectGroupVar defaultVar : defaultCodeMap.values()) {
			boolean find = false;
			for (ProjectGroupVar currentVar : allVars) {
				if (StringHelper.equals(defaultVar.getFullCode(), currentVar.getFullCode())) {
					find = true;
					break;
				}
			}
			if (!find) {
				defaultVar.setProject_id(project_id);
				varDao.insert(defaultVar);
				allVars.add(defaultVar);
			}
		}
	}
	
	private void loadAllRunningProjects() throws SQLException, ProjectNotExists {
		List<WeiXinProject> projectList = projectDao.getAllByStatus(WeiXinProjectStatus.START);
		if (projectList == null) {
			projectList = new LinkedList<WeiXinProject>();
		}
		List<WeiXinProject> newList = projectDao.getAllByStatus(WeiXinProjectStatus.TEST);
		if (newList != null) {
			projectList.addAll(newList);
		}
		newList = projectDao.getAllByStatus(WeiXinProjectStatus.INIT);
		if (newList != null) {
			projectList.addAll(newList);
		}
		if(projectList.isEmpty()){
			log.warn("...............................未发现启动状态项目....................................");
		}
		
		for (WeiXinProject project : projectList) {
			createNewOrRefresh(project);
		}
	}

	
	public static void createNewOrRefresh(WeiXinProject project) throws SQLException, ProjectNotExists {
		if (project == null) {
			throw new ProjectNotExists();
		}
		Collection<ProjectGroupVar> allVars = varDao.getByProjectId(project.getId());
		if (allVars == null) {
			allVars = defaultCodeMap.values();
			storeNewProjectVars(project.getId());
		} else {
			deleteNotUsedAndInsertNew(project.getId(), allVars);
		}
		Map<String, ProjectGroupVar> vars = new HashMap<String, ProjectGroupVar>();
		for (ProjectGroupVar var : allVars) {
			vars.put(var.getFullCode(), var);
		}
		codeMap.put(project.getId(), vars);
		projects.put(project.getId(), project);
	}
	
	public static void createNewOrRefresh(long project_id) throws SQLException, ProjectNotExists {
		WeiXinProject project = projectDao.getById(project_id);
		if (project == null) {
			throw new ProjectNotExists(project_id);
		}
		createNewOrRefresh(project);
	}

	public static void remove(long project_id) throws SQLException {
		codeMap.remove(project_id);
		projects.remove(project_id);
	}
	
	public static void delete(long project_id) throws SQLException {
		codeMap.remove(project_id);
		varDao.deleteByProjectId(project_id);
		projects.remove(project_id);
	}
	
	public static ProjectGroupVar get(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		Map<String, ProjectGroupVar> vars = codeMap.get(project_id);
		if (vars == null) {
			throw new ProjectNotExists(project_id);
		}
		ProjectGroupVar exp = vars.get(fullcode);
		if (exp == null) {
			throw new ProjectVarNotExists(project_id,fullcode);
		}
		return exp;
	}
	
	public static void update(long project_id,String fullcode,Object value) throws SQLException{
		Map<String, ProjectGroupVar> vars = codeMap.get(project_id);
		if (vars == null) {
			throw new ProjectNotExists(project_id);
		}
		ProjectGroupVar exp = vars.get(fullcode);
		if (exp == null) {
			throw new ProjectVarNotExists(project_id,fullcode);
		}
		exp.setValue(value);
		varDao.updateById(exp.getId(),value.toString());
	}
	
	public static Object get(long project_id, String group, String code) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, group + "." + code);
		if (exp == null)
			throw new GroupCodeIsNotExists(group, code);
		return exp.getValue();
	}
	
	public static int getInt(long project_id, String group, String code) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, group + "." + code);
		if (exp == null)
			throw new GroupCodeIsNotExists(group, code);
		try {
			return Integer.parseInt(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static int getInt(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		try {
			return Integer.parseInt(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static boolean getBool(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		try {
			return Boolean.parseBoolean(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	public static boolean getBool(long project_id, String fullcode, boolean default_value) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		try {
			return Boolean.parseBoolean(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return default_value;
		}
	}
	
	public static long getLong(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		if (exp.getValue() instanceof Integer)
			return (Integer) exp.getValue();
		try {
			return Long.parseLong(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static long getLong(long project_id, String group, String code) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, group + "." + code);
		if (exp == null)
			throw new GroupCodeIsNotExists(group, code);
		if (exp.getValue() instanceof Integer)
			return (Integer) exp.getValue();
		try {
			return Long.parseLong(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static double getDouble(long project_id, String group, String code) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, group + "." + code);
		if (exp == null)
			throw new GroupCodeIsNotExists(group, code);
		try {
			return Double.parseDouble(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static double getDouble(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		try {
			return Double.parseDouble(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}
	
	public static float getFloat(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		try {
			return Float.parseFloat(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
		
	}
	
	public static boolean _bool(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		try {
			return Boolean.parseBoolean(exp.getValue().toString());
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	public static String getStr(long project_id, String group, String code) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, group + "." + code);
		if (exp == null)
			throw new GroupCodeIsNotExists(group, code);
		return (String) exp.getValue();
	}
	
	public static String getStr(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		if (exp.getValue() != null)
			return exp.getValue().toString();
		return "";
	}
	
	public static String desc(long project_id, String fullcode) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, fullcode);
		if (exp == null)
			throw new GroupCodeIsNotExists(fullcode);
		return (String) exp.getDesc();
	}
	
	public static String desc(long project_id, String group, String code) throws ProjectNotExists, ProjectVarNotExists {
		ProjectGroupVar exp = get(project_id, group + "." + code);
		if (exp == null)
			throw new GroupCodeIsNotExists(group, code);
		return (String) exp.getDesc();
	}
	
}
